import { MAXSREEN, NORMAL, SMALLSREEN } from '@/assets/js/dialogStatus'
import { MessageConfig, AliveBar, State, Message } from '@/winTypes'

export const getStoreOption = () => {
  return {
    state: {
      currentZindex: 10,
      currentId: 0,
      currentIdIndex: 0,
      // defaultWidth: '910px',
      // defaultHeight: '640px',
      defaultWidth: 990,
      defaultHeight: 550,
      aliveBarList: [],
      isToSmall: false,
      viewportWidth: window.innerWidth,
      viewportHeight: window.innerHeight,
      messageList: [],
      noticeShow: false
    },
    getters: {
      getAliveBarList(state: State) {
        return state.aliveBarList
      },
      getAliveBar: (state: State) => (id: number) => {
        return state.aliveBarList.find((item) => {
          return item.id === id
        })
      }
    },
    mutations: {
      /**
       * 桌面（navbar）点击图标添加新的存活导航
       * @param state
       * @param aliveBar 接受的要添加的导航数据
       */
      addaliveBar(state: State, aliveBar: AliveBar) {
        state.currentZindex++
        let newAliveBar = {
          ...aliveBar,
          id: state.currentIdIndex,
          width: state.defaultWidth,
          height: state.defaultHeight,
          left: (state.viewportWidth - state.defaultWidth) / 2,
          top: (state.viewportHeight - state.defaultHeight) / 2,
          alive: true,
          status: NORMAL,
          statusHistory: NORMAL,
          zindex: state.currentZindex,
          toSmall() {
            this.status = SMALLSREEN
            state.isToSmall = true
          },
          toBig() {
            this.status = MAXSREEN
            this.statusHistory = MAXSREEN
          },
          toNormal() {
            this.status = NORMAL
            this.statusHistory = NORMAL
          },
          close() {
            // state.aliveBarList.splice
          }
        }
        // 将初始化的导航对象添加至vuex中存活列表中
        state.aliveBarList.push(newAliveBar)
        state.currentIdIndex++

        // 创建新的导航，把焦点转移到新添加的弹框上，任务栏对应也要把焦点转移到对应的导航图标上
        // 所以要关闭这个最小化表示
        state.isToSmall = false
      },
      /**
       *  用于用户再弹框的焦点转化（即点击被覆盖的弹框要让点击的弹框出现在最上层（zindex>max））
       * @param state
       * @param route 接收的弹框的route信息（用作与检索标识，唯一）
       */
      setBigZIndex(state: State, option: any) {
        // 如果传入的是导航对象
        if (option && option.zindex && option.route) {
          if (option.zindex === state.currentZindex) {
            return
          } else {
            state.currentZindex++
            option.zindex = state.currentZindex
            return
          }
        }
        state.aliveBarList.forEach((aliveBar, index) => {
          if (option.route) {
            if (aliveBar.route === option.route) {
              if (state.aliveBarList[index].zindex === state.currentZindex) {
                return
              } else {
                state.currentZindex++
                state.aliveBarList[index].zindex = state.currentZindex
                return
              }
            }
          }
        })
      },
      /**
       *  用于桌面图标点击，当弹框已经打开且处于最小化时，恢复到最小化之前
       * @param state
       * @param route 接收的弹框的route信息（用作与检索标识，唯一）
       */
      resetStatus(state: State, navBar: any) {
        // 找到存活的导航列表中对应的导航
        let findResult = state.aliveBarList.find((item) => {
          return item.id === navBar.id
        })
        // 判断当前导航是不是最上层
        if (navBar.zindex === state.currentZindex) {
          // 如果是最上层则判断是否处于最小化状态
          if (findResult?.status === SMALLSREEN) {
            // 取消最小化，回复到窗口状态
            findResult && (findResult.status = findResult.statusHistory)
            state.isToSmall = false
          } else {
            // 状态切换至最小化状态
            findResult && (findResult.status = SMALLSREEN)
            state.isToSmall = true
          }
        } else {
          // state.currentId++
          // 1.如果窗口是最小化，则恢复到历史窗口状态
          if (findResult?.status === SMALLSREEN) {
            findResult && (findResult.status = findResult.statusHistory)
          }
          // 2. 如果不是最上层，则将窗口的Zindex设置成最大
          state.currentZindex++
          findResult && (findResult.zindex = state.currentZindex)
        }
        // 将焦点切换至当前导航
        state.currentId = navBar.id
      },
      /**
       * 用于弹框上‘最小化按钮’&&任务栏重复点击同一个导航以实现展示和最小化的操作
       * @param state
       * @param id 要最小化的导航id
       */
      smallDialog(state: State, id: number) {
        let findResult = state.aliveBarList.find((item) => {
          return item.id === id
        })
        //  找到要最小化的导航
        if (findResult) {
          // 将此导航的状态切换为最小化以实现隐藏
          findResult.status = SMALLSREEN
          // 最小化后要将桌面激活的焦点导航取消
          state.isToSmall = true
        }
      },
      /**
       *  用于弹框上‘最大化按钮’
       * @param state
       * @param id 要最大化的导航id
       */
      maxDialog(state: State, id: number) {
        state.aliveBarList.forEach((aliveBar, index) => {
          // 找到此导航
          if (aliveBar.id === id) {
            // 如果已经处于最大化了，将状态切换为窗口默认状态NORMAL,并且记录当前窗口状态
            if (aliveBar.status === MAXSREEN) {
              aliveBar.status = NORMAL
              aliveBar.statusHistory = NORMAL
            } else if (aliveBar.status === NORMAL) {
              // 如果处于窗口状态，将状态切换未最大化MAXSREEN
              aliveBar.status = MAXSREEN
              aliveBar.statusHistory = MAXSREEN
            }
            return
          }
        })
      },
      /**
       * 用于弹框上‘关闭按钮’，销毁当前导航
       * @param state
       * @param id 要销毁的导航id
       */
      closeDialog(state: State, id: number) {
        state.aliveBarList.forEach((aliveBar, index) => {
          // 找到此导航
          if (aliveBar.id === id) {
            aliveBar.alive = false
            setTimeout(() => {
              // 将此导航从激活的导航列表中移除
              state.aliveBarList.splice(index, 1)
              // 定时间隔跟弹框消失动画对应，避免动画还没结束就从数组删掉
              // ps:因为v-for导致本有的东西移除，不享受vue过渡效果
            }, 500)
            // 关闭弹框之后，移除焦点（同最小化）
            state.isToSmall = true
            return
          }
        })
      },
      /**
       * 用于任务栏切换当前弹框（导航）功能
       * @param state
       * @param navBar 要切换的导航对象（navBar）
       */
      toTop(state: State, navBar: any) {
        // 重新激活焦点功能
        state.isToSmall = false
        // 找到存活的导航列表中对应的导航
        let findResult = state.aliveBarList.find((item) => {
          return item.id === navBar.id
        })
        // 判断当前导航是不是最上层
        if (navBar.zindex === state.currentZindex) {
          // 如果是最上层则判断是否处于最小化状态
          if (findResult?.status === SMALLSREEN) {
            // 取消最小化，回复到窗口状态
            findResult && (findResult.status = findResult.statusHistory)
            state.isToSmall = false
          } else {
            // 状态切换至最小化状态
            findResult && (findResult.status = SMALLSREEN)
            state.isToSmall = true
          }
        } else {
          // state.currentId++
          // 1.如果窗口是最小化，则恢复到历史窗口状态
          if (findResult?.status === SMALLSREEN) {
            findResult && (findResult.status = findResult.statusHistory)
          }
          // 2. 如果不是最上层，则将窗口的Zindex设置成最大
          state.currentZindex++
          findResult && (findResult.zindex = state.currentZindex)
        }
        // 将焦点切换至当前导航
        state.currentId = navBar.id
      },
      setIsToSmall(state: State, flag: boolean) {
        state.isToSmall = flag
      },
      addMessageList(state: State, message: Message) {
        if (message.type === 'loading') {
          Object.assign(message, {
            change(option: { type: string; text: string; always?: boolean }) {
              let findResult = state.messageList.find((item) => {
                return item.id === message.id
              })
              if (findResult) {
                findResult.type = option.type
                findResult.message = option.text
                if (option.always) {
                  findResult.always = option.always
                } else {
                  setTimeout(
                    () => {
                      findResult ? (findResult.alive = false) : ''
                    },
                    message.duration ? message.duration : 3000
                  )
                }
              }
            }
          })
        }
        state.messageList.push(message)
      },
      removeMessageList(state: State, id: number) {
        // let findIndex = -1
        state.messageList.forEach((item, index) => {
          if (item.id === id) {
            if (!state.messageList[index].always) {
              return (state.messageList[index].alive = false)
            }
          }
        })
        // 清除历史记录
        // let currentLength = state.messageList.length
        // setTimeout(() => {
        //   if (currentLength === state.messageList.length) {
        //     state.messageList = state.messageList.filter((item) => {
        //       return item.alive
        //     })
        //   }
        // }, 5000)
      },
      removeNoticeList(state: State, id: number) {
        if (id === -1) {
          let forindex = 0
          while (
            state.messageList.filter((item) => {
              return !item.alive
            }).length !== 0
          ) {
            if (state.messageList[forindex].alive) {
              forindex++
            } else {
              state.messageList.splice(forindex, 1)
            }
          }
          setTimeout(() => {
            state.noticeShow = false
          }, 600)
        } else {
          state.messageList.forEach((item, index) => {
            if (item.id === id) {
              if (!state.messageList[index].alive) {
                state.messageList.splice(index, 1)
                setTimeout(() => {
                  if (state.messageList.length === 0) {
                    state.noticeShow = false
                  }
                }, 600)
                return
              }
            }
          })
        }
      },
      changeNotice(state: State, show: boolean) {
        state.noticeShow = show
      }
    },
    actions: {
      addMessage(context: any, config: MessageConfig) {
        let id = new Date().getTime()
        let newConfig = {
          ...config,
          id: id,
          alive: true
        }
        context.commit('addMessageList', newConfig)
        // 如果没有常显，则定时3s关闭
        if (!config.always) {
          setTimeout(
            () => {
              context.commit('removeMessageList', id)
            },
            newConfig.duration ? newConfig.duration : 2200
          )
        }
        return newConfig
      }
    },
    modules: {}
  }
}
